export const hasHashUrl = (url = location.href): boolean => url.includes('#/')

/**
 * 获取一个 url 的基本部分，即不包括 hash
 * @param {String} url url
 * @returns {String}
 */
export const getUrlBase = (url = location.href): string => {
  const hashIndex = url.indexOf('#')
  const tmp = hashIndex === -1 ? url.slice(0) : url.slice(0, hashIndex)
  return tmp.replaceAll('?&', '?')
}

/**
 * 获取 url 的 fragment（即 hash 中去掉 # 的剩余部分）
 * @param {String} url url
 * @returns {String}
 */
export const getUrlHashFragment = (url = location.href): string => {
  const hashIndex = url.indexOf('#')
  const tmp = hashIndex === -1 ? '' : url.slice(hashIndex + 1)
  return tmp.replaceAll('?&', '?')
}

export const getUrlSearchFragment = (url = location.href): string => {
  const baseUrl = getUrlBase(url)
  const searchIndex = baseUrl.indexOf('?')
  const tmp = searchIndex === -1 ? '' : baseUrl.slice(searchIndex + 1)
  return tmp.replaceAll('?&', '?')
}

/**
 * 传入对象返回url参数
 * @param fragment
 * @param {Object} options {a:1}
 * @returns {string}
 */
export const getUrlParamFromFragment = (options: any, fragment = ''): string => {
  for (const tmp in options) {
    const arg = tmp,
      val = options[tmp] !== undefined ? options[tmp] : ''
    const pattern = arg + '=([^&]*)'
    const replaceText = arg + '=' + val
    fragment = fragment.match(pattern)
      ? fragment.replace(eval('/(' + arg + '=)([^&]*)/gi'), replaceText)
      : fragment.match('[?]')
        ? fragment + '&' + replaceText
        : fragment + '?' + replaceText
  }
  fragment = fragment.replaceAll('&&', '&')
  fragment = fragment.replaceAll('?&', '?')
  return fragment
}

/**
 * 删除URL参数
 * @param {*} url
 * @param {*} name
 */
export const deleteUrlParam = (name: string, url = location.href): string => {
  let str = ''
  if (url.indexOf('?') !== -1) str = url.substring(url.indexOf('?') + 1)
  else return url
  let arr = null
  let out = ''
  if (str.indexOf('&') !== -1) {
    arr = str.split('&')
    for (const i in arr) {
      if (arr[i].split('=')[0] !== name) {
        out = out + arr[i].split('=')[0] + '=' + arr[i].split('=')[1] + '&'
      }
    }
    return url.substring(0, url.indexOf('?')) + '?' + out.substring(0, out.length - 1)
  } else {
    arr = str.split('=')
    if (arr[0] === name) return url.substring(0, url.indexOf('?'))
    else return url
  }
}

/**
 * 格式化拼装Url参数
 * @param {*} url
 * @param {*} options
 */
export const formatUrlSearch = (options: any, url = location.href): string => {
  const hash = getUrlHashFragment(url)
  return getUrlParamFromFragment(options, getUrlBase(url)) + (!hash ? '' : '#' + hash)
}

/**
 * 格式化拼装hash参数Url
 * @param {*} url
 * @param {*} options
 */
export const formatUrlHash = (options: any, url = location.href): string => {
  const hash = getUrlHashFragment(url)
  const baseUrl = getUrlBase(url)
  const newHash = getUrlParamFromFragment(options, hash)
  return baseUrl + (newHash ? '#' + newHash : '')
}

/**
 * 给url插入或者修改参数
 * @param {*} url
 * @param {*} name
 * @param {*} value
 */
export const appendUrlSearch = (name: string, value: string, url = location.href) => formatUrlSearch({ [name]: value }, url)

/**
 * 给url hash部分插入或者修改参数
 * @param {*} url
 * @param {*} name
 * @param {*} value
 */
export const appendUrlHash = (name: string, value: string, url = location.href) => formatUrlHash({ [name]: value }, url)

export const appendUrl = (name: string, value: string, url = location.href): string => {
  if (hasHashUrl(url)) {
    return appendUrlHash(name, value, url)
  } else {
    return appendUrlSearch(name, value, url)
  }
}

/**
 * 删除url参数
 * @param {*} url
 * @param {*} name
 */
export const deleteUrlSearch = (name: string, url = location.href) => {
  const hash = getUrlHashFragment(url)
  return deleteUrlParam(name, getUrlBase(url)) + (!hash ? '' : '#' + hash)
}

/**
 * 删除url hash部分参数
 * @param {*} url
 * @param {*} name
 */
export const deleteUrlHash = (name: string, url = location.href) => {
  const newHash = deleteUrlParam(name, getUrlHashFragment(url))
  return getUrlBase(url) + (newHash ? '#' + newHash : '')
}

/**
 * 获取url指定的参数
 * @param {*} url
 * @param name
 */
export const getUrlSearchParam = (name: string, url = location.href): string | null => {
  const query = getUrlSearchFragment(url)
  const vars = query.split('&')
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split('=')
    if (pair[0] === name) {
      return pair[1]
    }
  }
  return null
}

/**
 * 获取url hash部分指定的参数
 * @param {*} url
 * @param name
 */
export const getUrlHashParam = (name: string, url = location.href): string | null => {
  let query = getUrlHashFragment(url)
  query = query.substring(query.indexOf('?') + 1, query.length)
  const vars = query.split('&')
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split('=')
    if (pair[0] === name) {
      return pair[1]
    }
  }
  return null
}

export const getUrlParam = (name: string, url = location.href): string | null => {
  const tmp = getUrlHashParam(name, url) || getUrlSearchParam(name, url)
  return tmp ? decodeURIComponent(tmp) : null
}

/**
 * 把一个字符串的 url 转为一个可获取其 base 和 fragment 等的对象
 *
 * @param {String} url url
 * @returns {UrlObject}
 */
export const toUrlJson = (url = location.href) => {
  const base = getUrlBase(url)
  const hash = getUrlHashFragment(url)
  const search = getUrlSearchFragment(url)
  return { base, original: url, search, hash }
}
